#include "Des.h"
#include <sstream>
#include <string>

// ConvertASCToByte 将ASCII码字符串压缩成16进制字符串,若有空余则以F填充
static bool ConvertASCToByte(unsigned char *desBuffer, std::string srcBuffer);

// ConvertByteToASC 将16进制字符串解压成ASCII码字符串
// Dest的有效长度大于2*Slen
static std::string ConvertByteToASC(unsigned char *Buffer, int BufferSize);

// CDES
CDes::CDes()
{
}

CDes::~CDes()
{
}

// 以CBC的模式计算
bool CDes::fnb3Des_CBC(const std::string &key, const std::string &data,
                       std::string &out)
{
    int len = data.size();
    if (key.size() != 32 || len % 16 != 0 || len == 0) {
        return false;
    }
    std::string vi("0000000000000000");
    std::string buffer1(data.substr(0, 16));
    std::string resEOR = fnsEOR(vi, buffer1);
    std::string buffer3DES;
    fnbTripleDESEncrypt(key, resEOR, buffer3DES);
    std::string _3DES = buffer3DES;
    for (int i = 1; i < len / 16; ++i) {
        std::string buffer(data.substr(16 * i, 16));
        resEOR = fnsEOR(buffer3DES, buffer);
        fnbTripleDESEncrypt(key, resEOR, buffer3DES);
        _3DES.append(buffer3DES);
    }
    out = _3DES;
    return true;
}

// 飞天卡,3DES MAC 计算
bool CDes::fnbMAC_3DES_FT(const std::string &IsKey,
                          const std::string &IsInitValue,
                          const std::string &IsDataIn, std::string &OsMAC)
{
    std::string LsData, sTemp;
    unsigned char LbyKeyL[8], LbyKeyR[8], LbyData[8], LbyDesRes[8], LbyTemp[32];
    unsigned char LiLen;

    //设置密钥
    ConvertASCToByte(LbyTemp, IsKey);
    memcpy(LbyKeyL, LbyTemp, 8);
    memcpy(LbyKeyR, LbyTemp + 8, 8);
    //设置初始向量
    ConvertASCToByte(LbyTemp, IsInitValue);
    memcpy(LbyDesRes, LbyTemp, 8);

    //整理数据块，后补80
    LsData = IsDataIn + "80";
    LiLen = LsData.length() % 16;
    if (LiLen > 0)  //需要补0的情况
    {
        for (int i = 0; i < 16 - LiLen; i++) LsData += '0';
    }

    //转换数据
    LiLen = LsData.length() / 16;  //最后数据块的个数，每个数据块16个字符长度

    for (int i = 0; i < LiLen; i++) {
        //取出16字节数据块Di
        sTemp = LsData.substr(16 * i, 16);
        //转换成8字节16进制块
        ConvertASCToByte(LbyData, sTemp);
        //和上次运算结果（有初始值）异或
        for (int j = 0; j < 8; j++) LbyData[j] = LbyData[j] ^ LbyDesRes[j];
        // DES 加密
        pDES(LbyData, LbyDesRes, LbyKeyL, true);
    }
    pDES(LbyDesRes, LbyDesRes, LbyKeyR, false);
    pDES(LbyDesRes, LbyDesRes, LbyKeyL, true);

    OsMAC = ConvertByteToASC(LbyDesRes, 8);

    return true;
}

//************************************************************************************************************************//
//												循环左移位一次
//  SubKeyPart : 源数据 28字节
//************************************************************************************************************************//
void CDes::pShiftL(unsigned char *SubKeyPart)
{
    unsigned char b = *SubKeyPart;

    //把SKP循环左移1次
    for (int i = 0; i < 27; i++) {
        SubKeyPart[i] = SubKeyPart[i + 1];
    }
    SubKeyPart[27] = b;
}
//************************************************************************************************************************//
//												计算子密钥
//  SubKey: 输出
//************************************************************************************************************************//
void CDes::pGetSubKey(const unsigned char Round, unsigned char *C,
                      unsigned char *D,
                      unsigned char *SubKey)  // C D 28字节  SubKey：48字节
{
    unsigned char b;
    // C, D分别循环左移,移动次数取决于密钥生成移位表(ShiftTable)的内容
    for (int i = 1; i <= ShiftTable[Round - 1]; i++) {
        pShiftL(C);
        pShiftL(D);
    }

    //利用置换距阵2，生成子密钥

    for (int i = 1; i <= 48; i++) {
        b = PC_2[i - 1];
        if (b <= 28)
            SubKey[i] = C[b - 1];
        else
            SubKey[i] = D[b - 28 - 1];
    }
}
//************************************************************************************************************************//
//										pSBoxChange
//
//************************************************************************************************************************//
void CDes::pSBoxChange(unsigned char *FR, unsigned char *FK,
                       unsigned char *Output)  // FR、FK:48字节  Output: 32字节
{
    unsigned char Temp1[49], Temp2[33];  // Temp1使用1-48， Temp2使用1-32

    for (int n = 1; n <= 48; n++) {
        Temp1[n] = FR[E[n - 1]] ^ FK[n];
    }

    for (int n = 1; n <= 8; n++) {
        int i = (n - 1) * 6;
        int j = (n - 1) * 4;
        int Row = Temp1[i + 1] * 2 + Temp1[i + 6];
        int Column = Temp1[i + 2] * 8 + Temp1[i + 3] * 4 + Temp1[i + 4] * 2 +
                     Temp1[i + 5];
        for (int h = 1; h <= 4; h++) {
            switch (h) {
                case 1:
                    Temp2[j + h] = (SBoxes[n - 1][Row][Column] & 8) / 8;
                    break;
                case 2:
                    Temp2[j + h] = (SBoxes[n - 1][Row][Column] & 4) / 4;
                    break;
                case 3:
                    Temp2[j + h] = (SBoxes[n - 1][Row][Column] & 2) / 2;
                    break;
                case 4:
                    Temp2[j + h] = (SBoxes[n - 1][Row][Column] & 1);
                    break;
            }
        }
    }
    for (int n = 1; n <= 32; n++) {
        *(Output + n) = Temp2[P[n - 1]];
    }
}
//************************************************************************************************************************//
//												取位函数
//
//************************************************************************************************************************//
unsigned char CDes::fnbyGetBit(const unsigned char *Data,
                               unsigned char Index)  //取位数据  Data :8字节
{
    Index = Index - 1;

    if ((Data[Index / 8] & (128 >> (Index % 8))) > 0)
        return 1;
    else
        return 0;
}
//************************************************************************************************************************//
//												置位函数
//
//************************************************************************************************************************//
void CDes::pSetBit(unsigned char *Output, unsigned char Index,
                   unsigned char Value)  //置位数据
{
    unsigned char Bit;
    Index = Index - 1;

    Bit = 128 >> (Index % 8);
    switch (Value) {
        // case 0: Output[Index / 8]=Output[Index / 8] & (~Bit);break;
        // case 1: Output[Index / 8]=Output[Index / 8] | Bit;break;
        case 0:
            *(Output + Index / 8) = *(Output + Index / 8) & (~Bit);
            break;
        case 1:
            *(Output + Index / 8) = *(Output + Index / 8) | Bit;
            break;
    }
}

//************************************************************************************************************************//
//                            DES算法
// Input： 输入数据 8字节二进制数,Output：DES结果数据，8字节二进制数,Key：
// 密钥
// ,EncryptID  ：加密/解密标志
//************************************************************************************************************************//
void CDes::pDES(const unsigned char *Input, unsigned char *Output,
                const unsigned char *Key, bool EncryptID)
{
    unsigned char InputValue[65], OutputValue[65], RoundKeys[17][49], L[33],
        R[33], FunctionResult[33];
    unsigned char  b;
    unsigned char C[29], D[29];

    //读入输入的64位码组
    for (int n = 1; n <= 64; n++)
        InputValue[n] = fnbyGetBit(Input, n);  // InputValue 使用 1-64

    //读入置换距阵1分别放入C, D中（按位放入）
    for (int n = 1; n <= 28; n++) {
        C[n] = fnbyGetBit(Key, PC_1[n - 1]);       // C 使用 1-28
        D[n] = fnbyGetBit(Key, PC_1[n + 28 - 1]);  // D 使用 1-28
    }
    //生成16个子密钥
    for (int n = 1; n <= 16; n++)
        pGetSubKey(n, C + 1, D + 1, RoundKeys[n]);  // RoundKeys使用[1-16][1-48]

    //把输入的64位码组分成两个32位的码组
    for (int n = 1; n <= 64; n++) {
        if (n <= 32)
            L[n] = InputValue[IP[n - 1]];  // L 使用 1-32
        else
            R[n - 32] = InputValue[IP[n - 1]];  // R 使用 1-32
    }

    for (int Round = 1; Round <= 16; Round++) {
        if (EncryptID)
            pSBoxChange(R, RoundKeys[Round],
                        FunctionResult);  // FunctionResult  使用 1-32
        else
            pSBoxChange(R, RoundKeys[17 - Round], FunctionResult);

        for (int n = 1; n <= 32; n++)
            FunctionResult[n] = FunctionResult[n] ^ L[n];

        //实现L<==R   R<==FunctionResult;
        for (int n = 1; n <= 32; n++) {
            L[n] = R[n];
            R[n] = FunctionResult[n];
        }
    }

    for (int n = 1; n <= 64; n++) {
        b = InvIP[n - 1];
        if (b <= 32)
            OutputValue[n] = R[b];
        else
            OutputValue[n] = L[b - 32];
    }
    for (int n = 1; n <= 64; n++)  // OutputValue  使用 1-64
    {
        pSetBit(Output, n, OutputValue[n]);
    }
}

//************************************************************************************************************************//
//												对输入字符串按位取反
// sInput : 输入串，ASCII格式 16字节   sOutput : 输出串
//************************************************************************************************************************//
bool CDes::fnbNOT(const std::string &sInput, std::string &sOutput)
{
    unsigned char bytTemp[8];  //用8字节

    if (!ConvertASCToByte(bytTemp, sInput)) return false;

    for (int i = 0; i < 8; i++) bytTemp[i] = ~bytTemp[i];

    sOutput = ConvertByteToASC(bytTemp, 8);
    return true;
}
//************************************************************************************************************************//
//												对输入字符串按位异或
//返回串 = IsStr1 ^ IsStr2;    IsStr1,IsStr2: 16字节
//************************************************************************************************************************//
std::string CDes::fnsEOR(const std::string &IsStr1,
                         const std::string &IsStr2)  // 16进制字符串异或
{
    unsigned char bytTemp1[8], bytTemp2[8], bytDes[8];  //用8字节
    std::string sReturn = "";

    if (ConvertASCToByte(bytTemp1, IsStr1) &&
        ConvertASCToByte(bytTemp2, IsStr2)) {
        for (int i = 0; i < 8; i++) {
            bytDes[i] = bytTemp1[i] ^ bytTemp2[i];
        }
        sReturn = ConvertByteToASC(bytDes, 8);
    }
    return sReturn;
}
//************************************************************************************************************************//
//                            DES算法
// IsKey：主密钥 32字节  IsDataIn： 输入串 16字节  IbEncrypt : 加解密标志
// &OsDataOut ：输出串 16字节
//************************************************************************************************************************//
bool CDes::fnbSingleDES(const std::string &IsKey, const std::string &IsDataIn,
                        bool IbEncrypt, std::string &OsDataOut)
{
    unsigned char LbyData[8], LbyDesRes[8], Lbykey[16];

    try {
        //换算密钥
        ConvertASCToByte(Lbykey, IsKey);
        // memmove(LbyRightKey,Lbykey+8,8);//Kr

        //换算源数据
        ConvertASCToByte(LbyData, IsDataIn);

        //计算DES
        pDES(LbyData, LbyDesRes, Lbykey, IbEncrypt);

        //转换为输出格式
        OsDataOut = ConvertByteToASC(LbyDesRes, 8);
        return true;
    } catch (void *) {
        return false;
    }
}
//************************************************************************************************************************//
//                            3-DES算法
// IsKey：主密钥 32字节  IsDataIn： 输入串 16字节  IbEncrypt : 加解密标志
// &OsDataOut ：输出串 16字节
//************************************************************************************************************************//
bool CDes::fnbTripleDES(const std::string &IsKey, const std::string &IsDataIn,
                        bool IbEncrypt, std::string &OsDataOut)
{
    unsigned char LbyRightKey[8], LbyData[8], LbyDesRes[8], Lbykey[16];

    try {
        //换算密钥
        ConvertASCToByte(Lbykey, IsKey);
        memmove(LbyRightKey, Lbykey + 8, 8);  // Kr

        //换算源数据
        ConvertASCToByte(LbyData, IsDataIn);

        //计算DES
        pDES(LbyData, LbyDesRes, Lbykey, IbEncrypt);
        pDES(LbyDesRes, LbyDesRes, LbyRightKey, !IbEncrypt);
        pDES(LbyDesRes, LbyDesRes, Lbykey, IbEncrypt);

        //转换为输出格式
        OsDataOut = ConvertByteToASC(LbyDesRes, 8);
        return true;
    } catch (void *) {
        return false;
    }
}

//************************************************************************************************************************//
//    fnbSingleDESEncrypt: DES加密
// IsKey：主密钥  IsDataIn： 输入串  &OsDataOut ：输出串
//************************************************************************************************************************//
bool CDes::fnbSingleDESEncrypt(const std::string &IsKey,
                               const std::string &IsDataIn,
                               std::string &OsDataOut)
{
    return fnbSingleDES(IsKey, IsDataIn, true, OsDataOut);
}

//************************************************************************************************************************//
//    fnbSingleDESDecrypt: DES解密
// IsKey：主密钥  IsDataIn： 输入串  &OsDataOut ：输出串
//************************************************************************************************************************//
bool CDes::fnbSingleDESDecrypt(const std::string &IsKey,
                               const std::string &IsDataIn,
                               std::string &OsDataOut)
{
    return fnbSingleDES(IsKey, IsDataIn, false, OsDataOut);
}

// CDes message handlers

//************************************************************************************************************************//
//    fnbTripleDESEncrypt: 3-DES加密
// IsKey：主密钥  IsDataIn： 输入串  &OsDataOut ：输出串
//************************************************************************************************************************//
bool CDes::fnbTripleDESEncrypt(const std::string &IsKey,
                               const std::string &IsDataIn,
                               std::string &OsDataOut)
{
    return fnbTripleDES(IsKey, IsDataIn, true, OsDataOut);
}

//************************************************************************************************************************//
//    fnbTripleDESDecrypt: 3-DES解密
// IsKey：主密钥  IsDataIn： 输入串  &OsDataOut ：输出串
//************************************************************************************************************************//
bool CDes::fnbTripleDESDecrypt(const std::string &IsKey,
                               const std::string &IsDataIn,
                               std::string &OsDataOut)
{
    return fnbTripleDES(IsKey, IsDataIn, false, OsDataOut);
}

//************************************************************************************************************************//
//    pGetDeriveKey :计算子密钥
// IsMasterKey: 主密钥 32字节   IsASN:
// 应用序列号，带入时20字节，在此用右16字节
// OsDeriveKey: 输出密钥 16字节
//************************************************************************************************************************//
bool CDes::fnbGetDeriveKey(const std::string &IsMasterKey,
                           const std::string &IsASN, std::string &OsDeriveKey)
{
    std::string KeyL, KeyR;  // 16 unsigned chars
    std::string sTemp1, sTemp2;

    sTemp1 = IsASN.substr(IsASN.size() - 16);
    if (!fnbNOT(sTemp1, sTemp2))  //取反操作, 结果到sTemp2
        return false;

    if (!fnbTripleDESEncrypt(IsMasterKey, sTemp1, KeyL) ||
        !fnbTripleDESEncrypt(IsMasterKey, sTemp2, KeyR)) {
        return false;
    }
    OsDeriveKey = KeyL + KeyR;
    return true;
}
//************************************************************************************************************************//
//    fnbGetSessionKey :计算过程密钥
////计算过程密钥，16字节密钥，8字节输入，8字节输出
//************************************************************************************************************************//
bool CDes::fnbGetSessionKey(const std::string &IsDeriveKey,
                            const std::string &IsDataIn,
                            std::string &OsSessionKey)
{
    return fnbTripleDESEncrypt(IsDeriveKey, IsDataIn, OsSessionKey);
}

//************************************************************************************************************************//
//    fnbMAC_DES :MAC - DEA 算法
// IsKey ：密钥 32字节  IsInitValue :初始值 16字节 “00 00 00 00 00 00 00 00”
// IsDataIn：数据块 16字节字符串（80字节16进制数）,如长度小于16字节，后面补
// 80
// 00 ...
// OSMac : 结果为8字节字符串（4字节16进制数）
//************************************************************************************************************************//
bool CDes::fnbMAC_DES(const std::string &IsKey, const std::string &IsInitValue,
                      const std::string &IsDataIn,
                      std::string &OsMAC)  // MAC - DEA 算法
{
    std::string LsData, sTemp;
    unsigned char LbyKey[8], LbyData[8], LbyDesRes[8], LbyTemp[32];
    unsigned char LiLen;

    try {
        //设置密钥
        ConvertASCToByte(LbyTemp, IsKey);
        memcpy(LbyKey, LbyTemp, 8);
        //设置初始向量
        ConvertASCToByte(LbyTemp, IsInitValue);
        memcpy(LbyDesRes, LbyTemp, 8);

        //整理数据块，后补80
        LsData = IsDataIn + "80";  // CARDIDENTIFY;
        LiLen = LsData.length() % 16;
        if (LiLen > 0)  //需要补0的情况
        {
            for (int i = 0; i < 16 - LiLen; i++) LsData += '0';
        }

        //转换数据
        LiLen =
            LsData.length() / 16;  //最后数据块的个数，每个数据块16个字符长度

        for (int i = 0; i < LiLen; i++) {
            //取出16字节数据块Di
            sTemp = LsData.substr(16 * i, 16);
            //转换成8字节16进制块
            ConvertASCToByte(LbyData, sTemp);
            //和上次运算结果（有初始值）异或
            for (int j = 0; j < 8; j++) LbyData[j] = LbyData[j] ^ LbyDesRes[j];
            // DES 加密
            pDES(LbyData, LbyDesRes, LbyKey, true);
        }

        OsMAC = ConvertByteToASC(LbyDesRes, 4);

        return true;
    } catch (void *) {
        return false;
    }
}
//************************************************************************************************************************//
//    fnbMAC_3DES :MAC - 3DEA 算法
// IsKey ：密钥 32字节  IsInitValue :初始值 16字节 “00 00 00 00 00 00 00 00”
// IsDataIn：数据块 16字节字符串（80字节16进制数）,如长度小于16字节，后面补
// 80
// 00 ...
// OSMac : 结果为8字节字符串（4字节16进制数）
//************************************************************************************************************************//
bool CDes::fnbMAC_3DES(
    const std::string &IsKey, const std::string &IsInitValue,
    const std::string &IsDataIn,
    std::string &OsMAC)  //计算MAC码(报文鉴别代码（Message Authentication Code)
{
    std::string LsData, sTemp;
    unsigned char LbyKeyL[8], LbyKeyR[8], LbyData[8], LbyDesRes[8], LbyTemp[32];
    unsigned char LiLen;

    try {
        //设置密钥
        ConvertASCToByte(LbyTemp, IsKey);
        memcpy(LbyKeyL, LbyTemp, 8);
        memcpy(LbyKeyR, LbyTemp + 8, 8);
        //设置初始向量
        ConvertASCToByte(LbyTemp, IsInitValue);
        memcpy(LbyDesRes, LbyTemp, 8);

        //整理数据块，后补80
        LsData = IsDataIn + "80";
        LiLen = LsData.length() % 16;
        if (LiLen > 0)  //需要补0的情况
        {
            for (int i = 0; i < 16 - LiLen; i++) LsData += '0';
        }

        //转换数据
        LiLen =
            LsData.length() / 16;  //最后数据块的个数，每个数据块16个字符长度

        for (int i = 0; i < LiLen; i++) {
            //取出16字节数据块Di
            sTemp = LsData.substr(16 * i, 16);
            //转换成8字节16进制块
            ConvertASCToByte(LbyData, sTemp);
            //和上次运算结果（有初始值）异或
            for (int j = 0; j < 8; j++) LbyData[j] = LbyData[j] ^ LbyDesRes[j];
            // DES 加密
            pDES(LbyData, LbyDesRes, LbyKeyL, true);
        }
        pDES(LbyDesRes, LbyDesRes, LbyKeyR, false);
        pDES(LbyDesRes, LbyDesRes, LbyKeyL, true);

        OsMAC = ConvertByteToASC(LbyDesRes, 4);

        return true;
    } catch (void *) {
        return false;
    }
}

//************************************************************************************************************************//
//    fnbTAC :计算TAC
// IsKey ：密钥 32字节
//************************************************************************************************************************//
bool CDes::fnbTAC(const std::string &IsKey, const std::string &IsInitValue,
                  const std::string &IsDataIn,
                  std::string &OsTAC)  // OsTAC : 8字节
{
    std::string LsKey_L, LsKey_R, LsTac_Key;
    LsKey_L = IsKey.substr(0, 16);
    LsKey_R = IsKey.substr(IsKey.size() - 16);

    LsTac_Key = fnsEOR(LsKey_L, LsKey_R);
    return fnbMAC_DES(LsTac_Key, IsInitValue, IsDataIn, OsTAC);
}

//************************************************************************************************************************//
//    fnbBlocksEncrypt_3DES :  数据块3-DES加密算法
// IsKey ：密钥 32字节字符串   IsDataIn: 数据块    OsDataOut: 输出数据块
//************************************************************************************************************************//
bool CDes::fnbBlocksEncrypt_3DES(
    const std::string &IsKey, const std::string &IsDataIn,
    std::string &OsDataOut)  // 3DES加密，16字节密钥，数据块
{
    unsigned char LbyLeftKey[8], LbyRightKey[8], LbyData[8], LbyDesRes[8],
        Lbykey[16], byLen[1];
    std::string data = IsDataIn;
    std::string LasBlock, LsData, sTemp;  //数据块
    int LiLen, LiRest;
    try {
        //换算密钥
        ConvertASCToByte(Lbykey, IsKey);
        memcpy(LbyLeftKey, Lbykey, 8);
        memcpy(LbyRightKey, Lbykey + 8, 8);

        //补加密数据长度Ld,加在第一字节
        byLen[0] = (unsigned char)data.length() / 2;
        sTemp = ConvertByteToASC(byLen, 1);
        data = sTemp + data;

        //最后数据块后补8000...
        LiLen = data.length();
        LiRest = LiLen % 16;  //注原系统是mod 8

        if (LiRest > 0)  // 说明数据块需要补齐
        {
            data += "80";
            LiRest += 2;
            for (int i = 0; i < 16 - LiRest; i++) data += '0';
        }
        //转换数据
        LiLen = data.length() / 16;  //最后数据块的个数，每个数据块16个字符长度

        OsDataOut = "";  //清空
        for (int i = 0; i < LiLen; i++) {
            //取出16字节数据块Di
            sTemp = data.substr(16 * i, 16);
            //转换成8字节16进制块
            ConvertASCToByte(LbyData, sTemp);

            // 3-DES 加密
            pDES(LbyData, LbyDesRes, LbyLeftKey, true);
            pDES(LbyDesRes, LbyDesRes, LbyRightKey, false);
            pDES(LbyDesRes, LbyDesRes, LbyLeftKey, true);

            sTemp = ConvertByteToASC(LbyDesRes, 8);
            OsDataOut += sTemp;
        }

        return true;
    } catch (void *) {
        // FErrMsg.MsgType:=mtApplication;FErrMsg.ErrMsg:='非法的数据';
        return false;
    }
}

//************************************************************************************************************************//
//    fnbBlocksEncrypt_3DES :  数据块3-DES解密算法
// IsKey ：密钥 32字节字符串   IsDataIn: 数据块    OsDataOut: 输入数据块
//************************************************************************************************************************//
bool CDes::fnbBlocksDecrypt_3DES(
    const std::string &IsKey, const std::string &IsDataIn,
    std::string &OsDataOut)  // 3DES解密，16字节密钥，数据块
{
    unsigned char LbyLeftKey[8], LbyRightKey[8], LbyData[8], LbyDesRes[8],
        Lbykey[16];

    std::string LasBlock, LsData, sTemp;  //数据块
    int LiLen, LiRealCount=0;
    try {
        //换算密钥
        ConvertASCToByte(Lbykey, IsKey);
        memcpy(LbyLeftKey, Lbykey, 8);
        memcpy(LbyRightKey, Lbykey + 8, 8);

        //数据解密
        LiLen = IsDataIn.length() / 16;  //数据块的个数，每个数据块16个字符长度
        OsDataOut = "";                  //清空
        for (int i = 0; i < LiLen; i++) {
            //取出16字节数据块Di
            sTemp = IsDataIn.substr(16 * i, 16);
            //转换成8字节16进制块
            ConvertASCToByte(LbyData, sTemp);

            // 3-DES 加密
            pDES(LbyData, LbyDesRes, LbyLeftKey, false);
            pDES(LbyDesRes, LbyDesRes, LbyRightKey, true);
            pDES(LbyDesRes, LbyDesRes, LbyLeftKey, false);

            if (i == 0){
                LiRealCount = LbyDesRes[0] * 2;  //取出实际数据块的长度Ld
            }
            sTemp = ConvertByteToASC(LbyDesRes, 8);
            OsDataOut += sTemp;
        }
        //拆分数据块
        OsDataOut = OsDataOut.substr(2, LiRealCount);

        return true;
    } catch (void *) {
        // FErrMsg.MsgType:=mtApplication;FErrMsg.ErrMsg:='非法的数据';
        return false;
    }
}

///////
std::string ConvertByteToASC(unsigned char *Buffer, int BufferSize)
{
    char cTemp[1024];
    std::string strResult;

    for (int i = 0; i < (int)BufferSize; i++) {
        sprintf(cTemp, "%x", Buffer[i] >> 4);
        strResult += cTemp;

        sprintf(cTemp, "%x", Buffer[i] & 0x0F);
        strResult += cTemp;
    }

    return strResult;
}
bool ConvertASCToByte(unsigned char *desBuffer, std::string srcBuffer)
{
    unsigned char byteTemp;
    char cTemp[2] = {'0', '\0'};
    int j = 0, iLength = srcBuffer.length();
    int iTemp;

    for (int i = 0; i < iLength; i++) {
        cTemp[0] = srcBuffer[i++];
        sscanf(cTemp, "%x ", &iTemp);  //把16进制字符串转成整数
        byteTemp = iTemp << 4;

        if (i != iLength) {
            cTemp[0] = srcBuffer[i];
            sscanf(cTemp, "%x ", &iTemp);
            byteTemp = byteTemp | iTemp;
        } else  //处理源buffer长度为奇数时，右端补 "F"
        {
            byteTemp = byteTemp | 0x0F;
        }

        desBuffer[j++] = byteTemp;
    }

    return true;
}
